using UnityEngine;
using System.Collections;

/// \class  gkSpawnTriggerInLine
/// \brief  Make is owner spawn a random number of actor in line
[AddComponentMenu("GK/Engine/Game/Spawn/gkSpawnTriggerInLine")]
public class gkSpawnTriggerInLine : gkSpawnTrigger 
{
    /// Stick offset
    public float StickOffset;

    /// Abscissa at which we attach an other actor on the line (in game width percent)
    public float AttachmentAbscissaInGameWidthPercent = 1.1f;

    /// The last spawned actor
    private GameObject m_rLastSpawnedActor;

    /// Abscissa at which we attach an other actor
    private float m_fAttachmentAbscissa;
    
    /// \brief  Called just after the game begin to play
    protected override void Start()
    {
        base.Start();

	    /// The game volume bounding box
	    Bounds oGameVolumeBoudingBox;

	    // Get the spawning volume bounding box
	    gkUtilityBounds.GrabColliderOrRendererBounds(GameObject.Find("GameVolume"), out oGameVolumeBoudingBox);;

	    // Compute the attachment Abscissa
	    m_fAttachmentAbscissa = oGameVolumeBoudingBox.min.x + 
		    AttachmentAbscissaInGameWidthPercent * (oGameVolumeBoudingBox.max.x - oGameVolumeBoudingBox.min.x);
    }

    /// \brief  Called at each actor spawn
    protected override void OnSpawnActor(GameObject a_rSpawnedActor)
    {
	    Bounds oLastSpawnedActorBoundingBox;
	    Bounds oNewSpawnedActorBoundingBox;
	    Vector3 f3SpawnLocation;

	    // If we already have spawned at least one actor
	    if(m_rLastSpawnedActor != null)
	    {
		    // Stick the new spawned actor with the last one
		    f3SpawnLocation = a_rSpawnedActor.transform.position;

		    // Compute the bounding box
			
			// Last spawned actor
			gkUtilityBounds.GrabRendererOrColliderBounds(m_rLastSpawnedActor, out oLastSpawnedActorBoundingBox);
			
			// New spawned actor
			gkUtilityBounds.GrabRendererOrColliderBounds(a_rSpawnedActor, out oNewSpawnedActorBoundingBox);

		    // Stick the end of the new one on the beginning of the last one
		    f3SpawnLocation.x = m_rLastSpawnedActor.transform.position.x + oLastSpawnedActorBoundingBox.extents.x
			     + oNewSpawnedActorBoundingBox.extents.x
			     + StickOffset;
			
		    // Set the spawn location
		    a_rSpawnedActor.transform.position = f3SpawnLocation;
	    }

	    // Save the last spawned actor
	    m_rLastSpawnedActor = a_rSpawnedActor;
    }

    /// \brief  Can we spawn again
    protected override bool CanSpawn()
    {
	    return m_rLastSpawnedActor == null || LastPawnNeedASuccessor();
    }

    /// \brief Test if the line need to be completed
    bool LastPawnNeedASuccessor()
    {
	    Bounds oLastSpawnedActorBoundingBox;

	    // Get the last spawned actor bounding box
	    gkUtilityBounds.GrabRendererOrColliderBounds(m_rLastSpawnedActor, out oLastSpawnedActorBoundingBox);

	    // Check if the last spawn will get pass the game volume
	    return oLastSpawnedActorBoundingBox.max.x <= (m_fAttachmentAbscissa + StickOffset);
    }
}
